package com.controller;

/**
 * Created by wlc on 2018/4/14.
 */

import com.entity.UserMetadata;
import com.service.DataAnalyseOperator;
import com.util.CookieUtil;
import com.util.FileUtil;
import com.util.LocalInformation;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import static com.util.PermissionUtil.isExperimentWrite;

/**
 * 映射实验部分
 */
@Controller
@RequestMapping(value = "/data_analyse", produces = "text/html;charset=UTF-8")
public class DataAnalyseController<train_cols> {

    @Autowired
    DataAnalyseOperator dataAnalyseService;


    @RequestMapping(value = "/data_analyse_page", produces = "text/html;charset=UTF-8")
    public ModelAndView data_input_experiment(HttpServletRequest request) {
        ModelAndView modelAndView = new ModelAndView();

        String user_cookie_value = CookieUtil.getUserCookie(request).getValue();
        if (user_cookie_value != null && UserMetadata.OnlineUserId.containsKey(user_cookie_value)) {
            UserMetadata.OnlineUserOperatorTime.replace(user_cookie_value, LocalInformation.getTimeID());
            if (isExperimentWrite(user_cookie_value.split("wlcniubi")[2])) {
                //进入数据导入界面
                int[] time = LocalInformation.getNowDate(new Date());
                modelAndView.addObject("time", time[0] + "-" + time[1] + "-" + time[2]);
                modelAndView.addObject("id", LocalInformation.getTimeID());
                modelAndView.addObject("author", user_cookie_value.split("wlcniubi")[1]);

                modelAndView.setViewName("data-analyze");
            } else {
                modelAndView.setViewName("Permission-Denied");
            }
        } else {
            modelAndView.setViewName("login");
        }

        return modelAndView;
    }

    /**
     * 模板下载
     *
     * @param request
     * @param response
     */
    @RequestMapping(value = "/template_download", produces = "text/html;charset=UTF-8")
    public void template_download(HttpServletRequest request, HttpServletResponse response) {
        String rootPath = request.getServletContext().getRealPath("/") + "/WEB-INF/template/";
        String fileName = "template.xlsx";
        FileUtil.file_download(rootPath, fileName, response);
    }

    /**
     * 结果下载
     *
     * @param request
     * @param response
     */
    @RequestMapping(value = "/result_download", produces = "text/html;charset=UTF-8")
    public void result_download(HttpServletRequest request, HttpServletResponse response) {
        for (Cookie cookie : request.getCookies()) {
            if (cookie.getName().equals("result_file_path")) {
                System.out.println(cookie.getValue());
                FileUtil.file_download("", cookie.getValue().replaceAll("tujunxiongniubi", "\\\\").replaceAll("menjinsuoniubi", " "), response);
            }
        }
    }

    /**
     * 训练文件上传
     *
     * @param request
     * @param response
     * @cookie train_file_path
     * @cookie train_file_upload_ts
     * @cookie file_upload_expire_time
     * @response status
     * @response msg (optional)
     * @response cols (optional)
     */
    @RequestMapping(value = "/upload_training_file", produces = "text/html;charset=UTF-8")
    public void train_file_upload(@RequestParam("excel_file") CommonsMultipartFile file,
                                  HttpServletRequest request,
                                  HttpServletResponse response) throws Exception, InterruptedException, InvalidFormatException {

        HashMap<String, String> msg = dataAnalyseService.validate(file);

        String result = "";
        if (msg.containsKey("status") && msg.get("status").equals("success")) {
            result = "{\"status\": \"" + "success" + "\", \"cols\": \"" + msg.get("cols") + "\"}";
            String file_abs_path = msg.get("file_abs_path").replaceAll("\\\\", "tujunxiongniubi").replaceAll(" ", "menjinsuoniubi");

            Cookie cookie = new Cookie("train_file_path", file_abs_path);
            cookie.setMaxAge(60);
            cookie.setPath("/");
            response.addCookie(cookie);

            cookie = new Cookie("train_file_uploaded", "true");
            cookie.setMaxAge(60);
            cookie.setPath("/");
            response.addCookie(cookie);
        } else {
            result = "{\"status\": \"failed\", \"msg\": \"" + msg.get("msg") + "\"}";
        }
        response.getWriter().write(result);
        response.setStatus(200);
    }

    /**
     * 开始训练
     *
     * @param request
     * @param response
     * @Param train_cols
     * @Param test_col
     * @cookie model_file_path
     * @cookie train_cols
     * @cookie test_col
     * @response status
     * @response msg (optional)
     * @response cols (optional)
     */
    @RequestMapping(value = "/start_training", produces = "text/html;charset=UTF-8")
    public void start_training(@RequestParam("train_cols") String train_cols_str,
                               @RequestParam("test_cols") String test_col,
                               HttpServletRequest request,
                               HttpServletResponse response) throws IOException, InterruptedException {
        System.out.println("train_cols:" + train_cols_str);
        System.out.println("test_cols:" + test_col);
        HashMap<String, String> msg = null;

        String train_file_path = null;
        String train_file_uploaded = null;
        String result = "";

        List<String> train_cols = Arrays.asList(train_cols_str.split(","));

        for (Cookie cookie : request.getCookies()) {
            if (cookie.getName().equals("train_file_path"))
                train_file_path = cookie.getValue().replaceAll("tujunxiongniubi", "\\\\").replaceAll("menjinsuoniubi", " ");
            if (cookie.getName().equals("train_file_uploaded")) train_file_uploaded = cookie.getValue();
        }

        if (train_file_path == null || train_file_uploaded == null) {
            result = "{\"status\": \"failed\", \"msg\": \"training file expired, please reupload\"}";
            response.getOutputStream().print(result);
            response.setStatus(200);
        } else if (!FileUtil.local_file_exist(train_file_path)) {
            result = "{\"status\": \"failed\", \"msg\": \"training file not found, please reupload\"}";
            response.getOutputStream().print(result);
            response.setStatus(200);
        } else {
            //执行 Python 脚本
            msg = dataAnalyseService.start_train(train_file_path, train_cols, test_col);
            if (msg != null && msg.containsKey("status") && msg.get("status").equals("success")) {
                result = "{\"status\": \"success\"}";

                Cookie cookie = new Cookie("model_file_path", msg.get("model_file_path").replaceAll("\\\\", "tujunxiongniubi").replaceAll(" ", "menjinsuoniubi"));
                cookie.setPath("/");
                response.addCookie(cookie);

                cookie = new Cookie("train_cols", StringUtils.join(train_cols, "tujunxiongniubi"));
                cookie.setPath("/");
                response.addCookie(cookie);


                cookie = new Cookie("test_cols", test_col);
                cookie.setPath("/");
                response.addCookie(cookie);

                cookie = new Cookie("model_file_existed", "true");
                cookie.setPath("/");
                cookie.setMaxAge(60);
                response.addCookie(cookie);
            } else if (msg != null) {
                result = "{\"status\": \"failed\", \"msg\": \"" + msg.get("msg") + "\"}";
            } else {
                result = "{\"status\": \"failed\"";
            }

            response.getOutputStream().print(result);
            response.setStatus(200);
            Thread.sleep(2000);
        }
    }

    /**
     * 测试文件上传
     *
     * @param request
     * @param response
     * @response status
     * @response msg (optional)
     * @response cols (optional)
     */

    @RequestMapping(value = "/start_predicting", produces = "text/html;charset=UTF-8")
    public void predict_file_upload(@RequestParam(value = "file") CommonsMultipartFile file,
                                    HttpServletRequest request,
                                    HttpServletResponse response) throws IOException, InterruptedException, InvalidFormatException {
        List<String> train_cols = null;
        String test_col = null;
        String model_file_path = null;
        String result = null;
        String model_file_existed = null;
        for (Cookie cookie : request.getCookies()) {
            if (cookie.getName().equals("train_cols"))
                train_cols = Arrays.asList(cookie.getValue().split("tujunxiongniubi"));
            if (cookie.getName().equals("model_file_path"))
                model_file_path = cookie.getValue().replaceAll("tujunxiongniubi", "\\\\").replaceAll("menjinsuoniubi", " ");
            if (cookie.getName().equals("test_cols")) test_col = cookie.getValue();
            if (cookie.getName().equals("model_file_existed")) model_file_existed = cookie.getValue();
        }
        if (train_cols == null || test_col == null || model_file_path == null || model_file_existed == null) {
            result = "{\"status\": \"failed\", \"msg\": \"Cookie validate error, please reupload training file\"}";
            response.getOutputStream().print(result);
            response.setStatus(200);
        } else {
            //进行推理
            HashMap<String, String> msg1 = dataAnalyseService.start_predict(file, model_file_path, null, train_cols, test_col);

            if (msg1.containsKey("status") && msg1.get("status").equals("success")) {
                result = "{\"status\": \"success\"}";

                Cookie cookie = new Cookie("result_file_path", msg1.get("result_file_path").replaceAll("\\\\", "tujunxiongniubi").replaceAll(" ", "menjinsuoniubi"));
                cookie.setPath("/");
                response.addCookie(cookie);

            } else {
                result = "{\"status\": \"failed\", \"msg\": \"" + msg1.get("msg") + "\"}";
            }
            response.getOutputStream().print(result);
            response.setStatus(200);

        }
        Thread.sleep(2000);
    }


}
